package com.gs.process.core.handler;

import cn.hutool.core.util.ClassUtil;
import com.gs.process.core.annotation.ProcessHandler;
import com.shallowUniverse.utils.BeanUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author gs
 * @date create in 2021/1/8 21:20
 */
public class ProcessHandlerHolder implements ProcessHandlerService {

    private Map<String, ProcessFinishedHandler> handlerFactory;

    public ProcessHandlerHolder(ApplicationContext context, String[] handlerPackages) {
        this.initializeBean(context, handlerPackages);
    }

    @Override
    public ProcessFinishedHandler generateHandler(String type) {
        return handlerFactory.get(type);
    }

    @Override
    public Map<String, ProcessFinishedHandler> getContext() {
        return this.handlerFactory;
    }

    /**
     * description: 初始化管理器 <br/>
     * author: gs   <br/>
     * date: 2021/1/17 <br/>
     * params: [] <br/>
     * return: void
     */
    public void initializeBean(ApplicationContext context, String[] handlerPackages) {
        //初始化容器
        this.handlerFactory = new HashMap<>();
        //加载处理器
        this.loadProcessHandlers(context, handlerPackages);
    }

    /**
     * description: 加载后置处理器 <br/>
     * author: Shuai Guo   <br/>
     * date: 2021/8/5 <br/>
     * params: [context, handlerPackages] <br/>
     * return: void <br/>
     * version: 1.0
     */
    private void loadProcessHandlers(ApplicationContext context, String[] handlerPackages) {
        //扫描处理器
        if (!ObjectUtils.isEmpty(handlerPackages)) {
            List<String> basePackages = Arrays.asList(handlerPackages);
            if (!CollectionUtils.isEmpty(basePackages)) {
                basePackages.stream().map(ClassUtil::scanPackage).forEach(classes -> classes.forEach(type -> {
                    //拿到注解判断是否有注解标识
                    ProcessHandler processHandler = type.getAnnotation(ProcessHandler.class);
                    if (!ObjectUtils.isEmpty(processHandler)) {
                        if (BeanUtil.isImplSuper(type, ProcessFinishedHandler.class)) {
                            //拿到要做后置处理的表名
                            String target = processHandler.value();
                            try {
                                //添加处理器
                                this.addHandler(target, type, context);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }));
            }
        }
    }

    /**
     * description: 加载处理器 <br/>
     * author: Shuai Guo   <br/>
     * date: 2021/7/21 <br/>
     * params: [key, type, context] <br/>
     * return: void <br/>
     * version: 1.0
     */
    private void addHandler(String key, Class<?> type, ApplicationContext context) throws IllegalAccessException, InstantiationException {
        if (!ObjectUtils.isEmpty(key) && !ObjectUtils.isEmpty(type)) {
            //实例化对象
            ProcessFinishedHandler processFinishedHandler = (ProcessFinishedHandler) type.newInstance();
            //如果是存在Spring容器中则装配bean
            context.getAutowireCapableBeanFactory().autowireBean(processFinishedHandler);
            //加入处理器工厂
            handlerFactory.put(key, processFinishedHandler);
        }
    }
}
